package com.itaq.cheetah.serviceB.controller;

import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.symmetric.AES;
import com.fasterxml.jackson.core.type.TypeReference;
import com.itaq.cheetah.serviceA.config.http.HttpRequest;
import com.itaq.cheetah.serviceA.config.web.dto.SsoSignSource;
import com.itaq.cheetah.serviceA.model.result.WrapperResult;
import com.itaq.cheetah.serviceA.model.vo.SsoUserInfo;
import com.itaq.cheetah.serviceA.utils.JsonUtils;
import com.itaq.cheetah.serviceB.dto.JsonRootBean;
import com.itaq.cheetah.serviceB.dto.RedirectData;
import com.itaq.cheetah.serviceB.dto.ToServiceAReq;
import com.itaq.cheetah.serviceB.properties.ConfigProperties;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.UUID;

/**
 * @author cheetah
 * @date 2022/7/25
 */
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/jumpA")
public class ToServiceAController {

    private final ConfigProperties configProperties;

    /**
     * 跳转 ServiceA 服务
     *
     *
     * @return ServiceA返回的重定向链接
     */
    @GetMapping
    public WrapperResult<RedirectData> redirectToServiceA() {
        //构建用户信息（模拟ServiceB带过来的用户信息）
        SsoUserInfo data = buildSsoUserInfo();
        Long timestamp = System.currentTimeMillis();
        String flowId = UUID.randomUUID().toString();
        String businessId = "sso";

        String dataEncrypt;
        String encryptType = configProperties.getEncryptType();
        //根据配置选择哪种方式加密
        switch (encryptType) {
            case "AES":
                AES aes = new AES(configProperties.getAppSecret().getBytes(StandardCharsets.UTF_8));
                dataEncrypt = aes.encryptBase64(JsonUtils.toString(data), StandardCharsets.UTF_8);
                break;
            case "RSA":
                RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), null, configProperties.getServiceAPublicKey());
                dataEncrypt = rsa.encryptBase64(JsonUtils.toString(data), StandardCharsets.UTF_8, KeyType.PublicKey);
                break;
            default:
                return WrapperResult.faild("未配置加密方式");
        }
        //将以下信息进行签名
        SsoSignSource build = SsoSignSource.builder()
                .platformId(configProperties.getAppId())
                .platformSecret(configProperties.getAppSecret())
                .businessId(businessId)
                .data(dataEncrypt)
                .flowId(flowId)
                .timestamp(timestamp)
                .build();
        String sign = build.sign();
        log.info("sign source={}", JsonUtils.toPrettyString(build));

        //构建请求体
        ToServiceAReq req = ToServiceAReq.builder()
                .platformId(configProperties.getAppId())
                .businessId("sso")
                .flowId(flowId)
                .timestamp(timestamp)
                .sign(sign)
                .data(dataEncrypt)
                .build();

        String s = HttpRequest.post("http://localhost:8081/serviceA")
                .bodyString(JsonUtils.toString(req))
                .execute()
                .asString();
        log.info("结果：{}", s);
        JsonRootBean jsonRootBean = JsonUtils.read(s, JsonRootBean.class);
        return WrapperResult.success(jsonRootBean.getData());
    }

    private SsoUserInfo buildSsoUserInfo() {
        SsoUserInfo userInfo = new SsoUserInfo();
        userInfo.setUserName("阿Q");
        userInfo.setPhone("qingqing-4132");
        userInfo.setIdName("欢迎添加阿Q微信:qingqing-4132");
        userInfo.setIdNumber("37123124578112X");
        return userInfo;
    }
}
